using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Mpi.Common;
using Xeml.Document;
using System.Linq;

namespace Xid.Controls.ParameterEditCtrls
{
    public partial class TimePointStackCtrl : UserControl
    {
        private TimePickComboCtrl lastTpc;
        private TimePickComboCtrl LastTpc
        {
            set
            {
                if (lastTpc != value)
                {
                    if (lastTpc != null)
                    {
                        lastTpc.AddPoint -= new EventHandler(OnAddPoint);
                        lastTpc.ShowExtendButton = false;
                    }
                    lastTpc = value;
                    if (lastTpc != null)
                    {
                        lastTpc.AddPoint += new EventHandler(OnAddPoint);
                        lastTpc.ShowExtendButton = true;
                    }
                }
            }
        }

        private LinkedList<TimePickComboCtrl> ctrls;


        private TimeSpan _maxTime = TimeSpan.MaxValue;
        public TimeSpan MaxTime
        {
            get { return _maxTime; }
            set
            {
                _maxTime = value;

                //if (lastTpc != null)
                //    lastTpc.MaxTime = _maxTime;
            }
        }

        private TimeSpan _minTime = TimeSpan.Zero;
        public TimeSpan MinTime
        {
            get { return _minTime; }
            set
            {
                _minTime = value;

                //if (this.ctrls.First != null)
                //    this.ctrls.First.Value.MinTime = _minTime;
            }
        }

        void OnAddPoint(object sender, EventArgs e)
        {

            AddPoint(this.ctrls.Last.Value.Time + TimeSpan.FromDays(1), false, false);

        }

        private void AddPoint(TimeSpan ts, bool batchMode, bool activated)
        {
            if (!batchMode)
                this.flowLayoutPanel1.SuspendLayout();
            TimePickComboCtrl tpc = new TimePickComboCtrl();
            tpc.Time = ts;
            
            tpc.Activated = activated;
            //tpc.MaxTime = _maxTime;
            tpc.Margin = new Padding(0);
            tpc.DropMe += new EventHandler(OnDropPoint);
            tpc.AddPoint += new EventHandler(OnAddPoint);
            tpc.TimeChanged += new EventHandler<PropertyHasChangedEventArgs<TimeSpan>>(OnPointChanged);
            tpc.GotSelected += new EventHandler(OnPointSelected);

            if (this.ctrls.Last != null)
            {
                this.ctrls.Last.Value.ShowExtendButton = false;
                this.ctrls.Last.Value.AddPoint -= new EventHandler(OnAddPoint);
                this.ctrls.Last.Value.EndLabel = "";
                //this.ctrls.Last.Value.MaxTime = ts - TimeSpan.FromSeconds(1);
                //tpc.MinTime = this.ctrls.Last.Value.Time + TimeSpan.FromSeconds(1);
            }
            else
            {
                //tpc.MinTime = _minTime;
            }


            tpc.EndLabel = "End";
            this.ctrls.AddLast(tpc);
            this.flowLayoutPanel1.Controls.Add(tpc);

            if (!batchMode)
                this.flowLayoutPanel1.ResumeLayout();

            //if (selectedCtrl != null)
            //    selectedCtrl.Selected = false;
            if (!batchMode)
                tpc.Selected = true;
            //this.selectedCtrl = tpc;
            if (!batchMode)
                if (PointAdded != null)
                {
                    PointAdded(this, new PropertyHasChangedEventArgs<TimeSpan>(tpc.Time, tpc.Time));
                }
        }


        TimePickComboCtrl selectedCtrl;
        void OnPointSelected(object sender, EventArgs e)
        {
            if (selectedCtrl != null && selectedCtrl != sender && this.ctrls.Contains(selectedCtrl))
                selectedCtrl.Selected = false;

            selectedCtrl = sender as TimePickComboCtrl;
            OnPointSelected(this, new PropertyHasChangedEventArgs<TimeSpan>(selectedCtrl.Time, selectedCtrl.Time));


        }

        void OnPointChanged(object sender, PropertyHasChangedEventArgs<TimeSpan> e)
        {
            //LinkedListNode<TimePickComboCtrl> tpc = this.ctrls.Find(sender as TimePickComboCtrl);
            //if (tpc.Previous != null)
            //{
            //    //tpc.Previous.Value.EndLabel = tpc.Value.StartLabel;
            //    //tpc.Previous.Value.MaxTime = tpc.Value.Time - TimeSpan.FromSeconds(1);
            //    //tpc.Value.MinTime = tpc.Previous.Value.Time + TimeSpan.FromSeconds(1);

            //}
            //if (tpc.Next != null)
            //{

            //    // tpc.Next.Value.MinTime = tpc.Value.Time + TimeSpan.FromSeconds(1);
            //    // tpc.Value.MinTime = tpc.Next.Value.Time - TimeSpan.FromSeconds(1);
            //}

            if (PointChanged != null)
                PointChanged(sender, e);
        }

        void OnPointSelected(object sender, PropertyHasChangedEventArgs<TimeSpan> e)
        {
            if (PointSelected != null)
                PointSelected(sender, e);
        }

        public TimePointStackCtrl()
        {
            this.ctrls = new LinkedList<TimePickComboCtrl>();
            InitializeComponent();
            TimePickComboCtrl tpc = new TimePickComboCtrl();
            this.flowLayoutPanel1.Controls.Clear();

            AddPoint(TimeSpan.Zero, false, false);
            //tpc.Margin = new Padding(0);
            //tpc.DropMe += new EventHandler(OnDropPoint);
            //tpc.AddPoint += new EventHandler(OnAddPoint);

            //foreach (TimePickComboCtrl tpc in this.flowLayoutPanel1.Controls)
            //{
            //    tpc.DropMe += new EventHandler(OnDropPoint);
            //    this.ctrls.AddLast(tpc);
            //}

            //this.ctrls.Last.Value.AddPoint += new EventHandler(OnAddPoint);
            //this.ctrls.Last.Value.ShowExtendButton = true;

            // LastTpc = (TimePickComboCtrl)this.flowLayoutPanel1.Controls[this.Controls.Count - 1];
        }


        //public void Populate(TimeSpan[] points)
        //{
        //    ClearPoints();
        //    this.flowLayoutPanel1.SuspendLayout();
        //    foreach (TimeSpan ts in points)
        //    {
        //        AddPoint(ts, true);
        //    }
        //    this.flowLayoutPanel1.ResumeLayout();
        //    this.ctrls.First.Value.Selected = true;
        //}


        DynamicTerm _currentVariable;
        List<TimeSpan> _underStartPoints = new List<TimeSpan>();
        public void Populate(StoryBase sb, DynamicTerm p)
        {
            TimeSpan start = TimeSpan.Zero;
            List<TimeSpan> currentTimePoints = new List<TimeSpan>();
            List<TimeSpan> allPoints = new List<TimeSpan>();

            if (sb is StorySplit)
                start = (sb as StorySplit).TimePoint;
            allPoints =  DocumentHelper.TimePointsOfAltering(sb.StoryBoard,start).ToList();
            if (!allPoints.Contains(start))
                allPoints.Add(start);
            if (p != null)
            {
                currentTimePoints.AddRange(p.Values.ListDistinctIdentifiers());
            }
       

            ClearPoints();
            
            allPoints.Sort();
            this.flowLayoutPanel1.SuspendLayout();

            foreach (TimeSpan ts in allPoints)
            {
                if (ts >= start)
                {
                    AddPoint(ts, true, currentTimePoints.Contains(ts));
                }

            }
            
            this.flowLayoutPanel1.ResumeLayout();
            this.ctrls.First.Value.Selected = true;
        }


        private TimePickComboCtrl FindControl(TimeSpan ts)
        {
            foreach (TimePickComboCtrl tp in this.ctrls)
            {
                if (tp.Time == ts)
                    return tp;

            }
            return null;
        }

        void OnDropPoint(object sender, EventArgs e)
        {


            TimePickComboCtrl tpc = sender as TimePickComboCtrl;
            DropPoint(tpc);
        }


        private void ClearPoints()
        {
            this.flowLayoutPanel1.SuspendLayout();
            foreach (TimePickComboCtrl tpc in this.ctrls)
            {

                tpc.DropMe -= new EventHandler(OnDropPoint);
                tpc.GotSelected -= new EventHandler(OnPointSelected);

                if (tpc == this.ctrls.Last.Value)
                {
                    tpc.AddPoint -= new EventHandler(OnAddPoint);

                }


            }
            this.flowLayoutPanel1.Controls.Clear();
            this.ctrls.Clear();
            this.flowLayoutPanel1.ResumeLayout();
        }



        private void DropPoint(TimePickComboCtrl tpc)
        {

            if (ctrls.Count > 1)
            {
                TimePickComboCtrl nextToSelect;
                LinkedListNode<TimePickComboCtrl> currNode = this.ctrls.Find(tpc);

                if (currNode.Next == null && currNode.Previous != null)
                {
                    currNode.Previous.Value.EndLabel = "End";

                    //currNode.Previous.Value.MaxTime = _maxTime;
                }
                //if (currNode.Next != null && currNode.Previous != null)
                //{
                //    //currNode.Previous.Value.EndLabel = currNode.Next.Value.StartLabel;
                //    //currNode.Previous.Value.MaxTime = currNode.Value.MaxTime;
                //}



                if (currNode.Next != null)
                    nextToSelect = currNode.Next.Value;
                else
                    nextToSelect = currNode.Previous.Value;


                this.flowLayoutPanel1.SuspendLayout();
                tpc.DropMe -= new EventHandler(OnDropPoint);
                tpc.GotSelected -= new EventHandler(OnPointSelected);

                if (tpc == this.ctrls.Last.Value)
                {
                    tpc.AddPoint -= new EventHandler(OnAddPoint);
                    this.ctrls.Remove(tpc);
                    this.ctrls.Last.Value.AddPoint += new EventHandler(OnAddPoint);
                    this.ctrls.Last.Value.ShowExtendButton = true;
                }



                this.ctrls.Remove(tpc);
                this.flowLayoutPanel1.Controls.Remove(tpc);
                this.flowLayoutPanel1.ResumeLayout();
                //((LastTpc = (TimePickComboCtrl)this.flowLayoutPanel1.Controls[this.Controls.Count - 1];

                if (PointDroped != null)
                {
                    PointDroped(this, new PropertyHasChangedEventArgs<TimeSpan>(tpc.Time, tpc.Time));
                }
                tpc.Dispose();
                nextToSelect.Selected = true;
            }
            else
            {
                if (PointDroped != null)
                {
                    PointDroped(this, new PropertyHasChangedEventArgs<TimeSpan>(tpc.Time, tpc.Time));
                }
                tpc.Time = TimeSpan.Zero;
                tpc.SetViewMode(true);
            }

        }

        public event EventHandler<PropertyHasChangedEventArgs<TimeSpan>> PointAdded;
        public event EventHandler<PropertyHasChangedEventArgs<TimeSpan>> PointDroped;
        public event EventHandler<PropertyHasChangedEventArgs<TimeSpan>> PointChanged;
        public event EventHandler<PropertyHasChangedEventArgs<TimeSpan>> PointSelected;


    }
}
